package com.smart.manager.system.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson2.JSONObject;
import com.smart.common.entities.constant.ArcoTips;
import com.smart.common.entities.constant.SmartConstant;
import com.smart.common.entities.core.Page;
import com.smart.common.entities.option.SelectOption;
import com.smart.manager.system.entities.body.RSystemAccount;
import com.smart.manager.system.entities.models.SystemAccount;
import com.smart.manager.system.entities.models.query.QSystemAccount;
import io.ebean.DB;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
@Log4j2
@RequiredArgsConstructor
public class AccountRepository {
    private final ConfigRepository configRepository;
    private final RoleRepository roleRepository;




    /**
     * 获取账号默认登录密码
     *
     * @return {@link String}
     */
    public String getDefaultPsw(){
        JSONObject jsonObject = configRepository.readCache(SmartConstant.ACCOUNT_CFG);
        return jsonObject.getString("password");
    }


    public Page<SystemAccount> pageList(RSystemAccount.SearchBody search) {
        QSystemAccount query = new QSystemAccount();
        Opt.ofBlankAble(search.getAccount()).ifPresent(x -> query.account.contains(x));
        Opt.ofBlankAble(search.getName()).ifPresent(x -> query.name.contains(x));
        Opt.ofBlankAble(search.getState()).ifPresent(x -> query.state.eq(x));
        Opt.ofBlankAble(search.getSex()).ifPresent(x -> query.sex.eq(x));
        Opt.ofBlankAble(search.getPhoneNumber()).ifPresent(x -> query.phoneNumber.contains(x));
        query.order().id.desc();
        query.setFirstRow(search.firstRow()).setMaxRows(search.maxRows());
        Page<SystemAccount> result = new Page<SystemAccount>().load(query.findPagedList());
        if (CollectionUtil.isNotEmpty(result.getRecords())) {
            //匹配角色信息
            List<SelectOption> options = roleRepository.getOptions(StrUtil.EMPTY);
            result.getRecords().forEach(item -> {
                List<String> roleNameList = options.stream()
                        .filter(x -> item.getRoleCodes().contains(x.getValue()))
                        .map(SelectOption::getLabel).collect(Collectors.toList());
                item.setRoleNames(roleNameList);



            });
        }
        return result;
    }





    public SystemAccount getAccountByPhoneNumber(String phoneNumber, boolean checkNull) {
        SystemAccount record = new QSystemAccount().phoneNumber.eq(phoneNumber).setMaxRows(1).findOne();
        if (checkNull) {
            Assert.notNull(record, "手机号码不存在");
        }
        return record;
    }


    private SystemAccount getOneById(Long id) {
        QSystemAccount query = new QSystemAccount();
        SystemAccount record = query.id.eq(id).setMaxRows(1).findOne();
        Assert.notNull(record, ArcoTips.UPDATE_NOT_FOUND);
        return record;
    }




    public String add(RSystemAccount.EditBody body) {

        QSystemAccount query = new QSystemAccount();
        SystemAccount record = query.account.eq(body.getAccount()).setMaxRows(1).findOne();
        Assert.isNull(record, "创建失败:, 账号代码已存在");
        SystemAccount accountByPhoneNumber = getAccountByPhoneNumber(body.getPhoneNumber(), false);
        Assert.isNull(accountByPhoneNumber, body.getPhoneNumber() + "这个手机号码已被注册过了");
        SystemAccount systemAccount = BeanUtil.copyProperties(body, SystemAccount.class);

        String psw = getDefaultPsw() ;
        String password = DigestUtil.bcrypt(psw);
        systemAccount.setPassword(password).save();
        log.warn("创建机构账号的同时创建机构数据");
        return "账号创建成功,登录密码为: ".concat(psw);
    }


    public void update(Long id, RSystemAccount.EditBody body) {

        SystemAccount account = getOneById(id);
        if (StrUtil.isNotBlank(body.getPhoneNumber()) && !account.getPhoneNumber().equals(body.getPhoneNumber())) {
            SystemAccount accountByPhoneNumber = getAccountByPhoneNumber(body.getPhoneNumber(), false);
            Assert.isNull(accountByPhoneNumber, "手机号码已被注册过了");
        }
        BeanUtil.copyProperties(body, account);
        Objects.requireNonNull(account).update();
    }

    public int delByIds(List<Long> ids) {
        List<SystemAccount> list = new QSystemAccount().id.in(ids).findList();
        Assert.notEmpty(list, ArcoTips.DELETE_NOT_FOUND);
        for (SystemAccount module : list) {

            log.warn("检查数据是否允许被删除  {}", module);
        }
        return DB.deleteAll(list);
    }




    public String resetPsw(Long id) {

        SystemAccount account = getOneById(id);
        String psw = getDefaultPsw();
        String newPsw = DigestUtil.bcrypt(psw);
        account.setPassword(newPsw).setLastPassTime(LocalDateTime.now());
        account.update();
        return "登录密码已重置为:" + psw;

    }

    /**
     * 获取数据字典下拉选项
     *
     * @return {@code List<SelectOption>}
     */
    public List<SelectOption> getOptions() {
        return new QSystemAccount().findStream()
                .map(x -> new SelectOption().setLabel(x.getName()).setValue(String.valueOf(x.getId())).setDisabled(false))
                .collect(Collectors.toList());
    }

    /**
     * 获取数据字典下拉选项
     *
     * @return {@code List<SelectOption>}
     */
    public List<SelectOption> getCustomerServiceOptions() {
        return new QSystemAccount().roleCodes.contains("KKK").findStream()
                .map(x -> new SelectOption().setLabel(x.getName()).setValue(String.valueOf(x.getId())).setDisabled(false))
                .collect(Collectors.toList());
    }


}
